/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-4-28 下午2:56 Created by dwzhang
 */
package com.jade.framework.base;

import java.io.File;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 对于系统System的扩充。
 *
 * @author dwzhang
 * @version 1.0 13-4-28 下午2:56
 */
public class JadeSystem
{
    private static Map<String, String> properties = new HashMap<String, String>();
    private static String hostname;
    private static final char[] ENCODER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
    /** 产品所在目录 */
    private static String home = null;
    //server type
    private static String serverType;

    /** JVM 唯一标识 */
    private static String identity = null;
    protected static Log log = LogFactory.getLog("jade.system");

    static {
        //产生JVM唯一标识
        //MD5加密
        StringBuilder key = new StringBuilder();
        try {
            InetAddress localhost = InetAddress.getLocalHost();
            String host = localhost.getHostAddress();
            hostname = localhost.getHostName();
            key.append(host);
        }
        catch (Exception e) {
            key.append(e.getMessage());
        }
        long time = System.currentTimeMillis();
        key.append(time);
        key.append(new Random(time).nextInt());
        byte[] md5 = DigestUtils.md5(key.toString());
        StringBuilder sb = new StringBuilder(8);
        for (int i = 0; i < md5.length; ) {
            sb.append(ENCODER[(md5[i++] & 0x30 | md5[i++] & 0x0F) % 36]);
        }
        identity = sb.toString();
        if (hostname == null) {
            hostname = identity;
        }
    }

    public static String getServerType()
    {
        return serverType;
    }

    public static void setServerType(String serverType)
    {
        JadeSystem.serverType = serverType;
    }

    public static Collection<InetAddress> getIpAddresses()
    {
        try {
            Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            Collection<InetAddress> addresses = new ArrayList<InetAddress>();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                Enumeration en = netInterface.getInetAddresses();
                while (en.hasMoreElements()) {
                    InetAddress ip = (InetAddress) en.nextElement();
                    addresses.add(ip);
                }
            }
            return addresses;
        }
        catch (Throwable t) {
            log.warn("Can't get network interfaces:", t);
            return CollectionUtils.EMPTY_COLLECTION;
        }
    }

    public static String getJvmIdentity()
    {
        return identity;
    }

    public static void setProperty(String key, String value)
    {
        properties.put(key, value);
    }

    public static String getProperty(String key)
    {
        String value = properties.get(key);
        if (value == null) {
            value = System.getProperty(key);
        }
        return value;
    }

    public static String getProperty(String key, String defValue)
    {
        String value = properties.get(key);
        if (value == null) {
            return System.getProperty(key, defValue);
        }
        else {
            return value;
        }
    }

    public static Map<String, String> getProperties()
    {
        return properties;
    }

    public static final String getHome()
    {
        if (home == null) {
            home = getProperty("product.home", "/jade/product");
        }
        return home;
    }

    /** 返回系统的主机名 */
    public static final String getHostName()
    {
        return hostname;
    }

    private static String libraryPath;

    /**
     * 根据操作系统类型返回不同的JNI目录
     * <p/>
     * 根据<code>home</code>参数来获取lib目录
     * 这个LibraryPath是区别于<code>java.library.path</code>的
     */
    public static final String getLibraryPath()
    {
        if (libraryPath == null) {
            String home = getHome();
            if (home != null) {
                StringBuilder sb = new StringBuilder(64);
                sb.append(home).append(File.separatorChar);
                sb.append("lib").append(File.separatorChar);
                sb.append("native").append(File.separatorChar);

                String osName = getOSName().toLowerCase();
                sb.append(osName);

                libraryPath = sb.toString();
            }
            else {
                libraryPath = "/usr/lib";
            }
        }

        return libraryPath;
    }

    /**
     * 根据操作系统类型返回不同的JNI目录
     * <p/>
     * 根据<code>home</code>参数来获取lib目录
     * 这个LibraryPath是区别于<code>java.library.path</code>的
     *
     * @param libName 库名
     */
    public static void loadLibrary(String libName)
    {
        System.load(getLibraryFile(libName).getAbsolutePath());
    }

    public static File getLibraryFile(String libName)
    {
        StringBuilder sb = new StringBuilder(getLibraryPath());
        sb.append(File.separatorChar).append(libName);
        return new File(sb.toString());
    }

    /**
     * 休眠时间
     *
     * @param time 时间
     */
    public static void sleep(long time)
    {
        try {
            Thread.sleep(time);
        }
        catch (Exception e) {
        }
    }

    /**
     * 休眠时间
     *
     * @param time 时间
     */
    public static void sleep(long time, int nanos)
    {
        try {
            Thread.sleep(time, nanos);
        }
        catch (Exception e) {
        }
    }

    private static String oSName = null;

    /**
     * 返回系统名称
     *
     * @return 系统名称
     */
    public static String getOSName()
    {
        if (oSName == null) {
            oSName = getProperty("os.name");
        }
        return oSName;
    }

    /**
     * 判断是否是Windows平台
     *
     * @return 是否是Windows平台
     */
    public static boolean isWindows()
    {
        return getOSName().indexOf("indows") >= 0;
    }

    /**
     * 返回系统版本
     *
     * @return 系统版本
     */
    public static String getOSVersion()
    {
        return getProperty("os.version");
    }

    /**
     * 返回Java版本信息
     *
     * @return Java版本信息
     */
    public static String getJavaVersion()
    {
        return getProperty("java.version");
    }

    /**
     * 返回Java说明版本信息
     *
     * @return "java.specification.version";
     */
    public static String getJavaSpecificationVersion()
    {
        return getProperty("java.specification.version");
    }

    public static Log getLog()
    {
        return log;
    }
}
